from flask import Blueprint, request, jsonify, make_response
from models import db, Task, TaskSchema
from sqlalchemy import or_,and_

from datetime import datetime, timedelta

tasks_bp = Blueprint('tasks', __name__)
task_schema = TaskSchema()
tasks_schema = TaskSchema(many=True)


# add one item
@tasks_bp.route('/', methods=['POST', 'OPTIONS'])
def create_task():
    print("POST method=", "add item")
    if request.method == 'OPTIONS':
        print(">>OPTIONS in create_task")
        #return jsonify({'error': 'Method is OPTIONS'}), 404
        return 'xx', 200 #这个必须有，否则报错，似乎第一次是 OPTIONS 请求，所谓的预请求？
    
    action = request.args.get('action')
    print(">>", "create_task: action=", action)

    # 新增
    user_id = request.json.get('user_id')
    title = request.json.get('title')
    description = request.json.get('description')
    priority = request.json.get('priority')

    due_date_str = request.json.get('due_date')
    due_date = datetime.strptime(due_date_str, '%Y-%m-%d').date() if due_date_str else None

    current_step = request.json.get("current_step", 0)
    total_steps = request.json.get("total_steps", 0)
    
    new_task = Task(user_id=user_id, title=title, description=description, priority=priority, due_date=due_date,
                    current_step=current_step, total_steps=total_steps)
    db.session.add(new_task)
    db.session.commit()
    
    return task_schema.jsonify(new_task), 201


@tasks_bp.route('/', methods=['GET'])
def get_tasks():
    print("get method=", "tasks")
    # url 参数?next_period=""
    next_period = request.args.get('next_period', '')
    print("next_period=", next_period)

    # 计算过去一个月的日期范围，互斥
    #now = datetime.utcnow()
    now = datetime.now()
    # 获取当天0点的时间
    now = now.replace(hour=0, minute=0, second=0, microsecond=0)

    next_season = now + timedelta(days=92)
    next_month = now + timedelta(days=30)
    next_week = now + timedelta(days=7)
    next_day = now + timedelta(days=1)

    if next_period in ("season","month", "week", "day"):
        if "season"==next_period:
            time1=next_month
            time2=next_season
        if "month"==next_period:
            time1=next_week
            time2=next_month
        elif "week"==next_period:
            time1=next_day
            time2=next_week
        elif "day"==next_period:
            time1=now
            time2=next_day

        # 只要日期，不要时间部分，解决不同类型比较的bug
        time1 = time1.date()
        time2 = time2.date()

        #time1 -= timedelta(microseconds=1) #不加这一句，>= time1: 2025-01-02 00:00:00 <class 'datetime.datetime'> 总数匹配不到 2025-01-02
        # print("\t>> time1=", time1, type(time1)) #<class 'datetime.datetime'>

        # 使用SQLAlchemy查询过去一个时间段的记录
        tasks = Task.query.filter( #保证[) 左闭右开 区间
            Task.due_date >= time1,
            Task.due_date < time2,
            (Task.completed == None) | (Task.completed == False)
        ).order_by(
            Task.due_date.asc()
        ).all()

        #for task in tasks:
        #    print("\t> task.due_date: ", task.due_date, type(task.due_date)) #<class 'datetime.date'>
    elif next_period == "due": #过期日程，且未完成
        #print("if2>, next_period=", next_period)
        now = datetime.now()
        tasks = Task.query.filter(
            Task.due_date < now,
            (Task.completed == None) | (Task.completed == False)
        ).order_by(
            Task.due_date.desc()
        ).all()
    elif next_period == "completed": #已完成
        #print("if3, next_period=", next_period)
        tasks = Task.query.filter(
            Task.completed == True
        ).order_by(
            Task.due_date.desc()
        ).all()
    elif next_period == "uncompleted": #未完成
        #print("if3, next_period=", next_period)
        tasks = Task.query.filter(
            (Task.completed == None) | (Task.completed == False)
        ).order_by(
            Task.due_date.asc()
        ).all()
    else:
        #print("else, next_period=", next_period)
        tasks = Task.query.order_by(Task.due_date.asc()).all() #desc, asc

    return tasks_schema.jsonify(tasks), 200


# 查询具体一个任务，通过 task_id
@tasks_bp.route('/<int:task_id>', methods=['GET'])
def get_task(task_id):
    print("get method=", task_id)
    task=Task.query.get(task_id)
    if task is None:
        return jsonify({'error': 'Task not found'}), 404
    return task_schema.jsonify(task), 201



#更新
@tasks_bp.route('/<int:task_id>', methods=['PUT', "OPTIONS"])
def update_task(task_id):
    task = Task.query.get(task_id)
    if not task:
        return jsonify({'error': 'Task not found'}), 404
    
    #print("1>>", dir(task) )
    #print("1.5>", request.json.get("completed"))

    #task.update(request.json)
    task.title = request.json.get("title", task.title)
    task.description = request.json.get("description", task.description)
    task.priority = request.json.get("priority", task.priority)

    task.current_step = request.json.get("current_step", task.current_step)
    task.total_steps = request.json.get("total_steps", task.total_steps)

    # for bool type
    completed=request.json.get("completed", task.completed)
    #print("-->0 completed=", completed)
    if isinstance(completed, str):
        #print("-->1 completed=", completed)
        task.completed = completed.lower() in ['true', '1', 't', 'y', 'yes']
    if isinstance(completed, bool):
        #print("-->2 completed=", completed)
        task.completed = completed

    # for date
    due_date_str = request.json.get("due_date", None)
    if due_date_str is not None:
        task.due_date = datetime.strptime(due_date_str, '%Y-%m-%d').date() if due_date_str else None

    #print("2>>", task, task.task_id, task.due_date, task.completed)
    #return jsonify({'error': 'Task not found'}), 404
    print("3>>", task, task.total_steps, task.current_step)

    db.session.commit()
    return task_schema.jsonify(task), 201


# INSERT INTO task (task_id, user_id, title, description, priority, due_date) VALUES (11, 1, '标题11', '内容11', 'high', '2024-07-05');
# 删除任务
@tasks_bp.route('/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    #task = Task.query.get(task_id)
    task = Task.query.get_or_404(task_id)
    db.session.delete(task)
    db.session.commit()
    print("delete task:", task_id)
    return '', 204
    #return task_schema.jsonify(task), 204











############################################
# 去年今日，去年接下来一周，接下俩一个月
############################################
# n=1表示去年，n=2表示前面2年


#获取配置文件
from config import Config
# 获取 n_years 值
n_years = Config.N_YEARS
# 计算今天的日期
today = datetime.now()
# 计算过去 n 年的日期: 计算严格的去年的今天和前年的今天
target_dates = [(today.replace(year=today.year - i)).date() for i in range(1, n_years + 1)]



# 去年今日，查询历史任务
@tasks_bp.route('/history', methods=['GET'])
def get_tasks_history():
    #print(">>>1. today:", today, " | ", target_dates)
    tasks_results = {
        "tasks_today": [],
        "tasks_next_week": [],
        "tasks_next_month": [],
        "n_years": n_years
    }

    for target_date in target_dates:
        # 每年的目标日期
        date_key = target_date.isoformat()  # 转换为字符串格式

        # 查询同一天的任务
        tasks_today = Task.query.filter(Task.due_date == target_date ).all()
        #print(tasks_today)
        tasks_results["tasks_today"].extend( [{
            "task_id": task.task_id,
            "title": task.title,
            "due_date": task.due_date.isoformat()
        } for task in tasks_today] ) # 假设您有 to_dict 方法

        # 查询下一周的任务
        next_week_start = target_date + timedelta(days=1)  # 从明天开始
        next_week_end = next_week_start + timedelta(days=7)
        tasks_next_week = Task.query.filter(Task.due_date >= next_week_start, Task.due_date < next_week_end).all()
        tasks_results["tasks_next_week"].extend( [{
            "task_id": task.task_id,
            "title": task.title,
            "due_date": task.due_date.isoformat()
        } for task in tasks_next_week] )

        # 查询下一个月的任务
        next_month_start = target_date + timedelta(days=8)  # 从明天开始
        next_month_end = next_month_start + timedelta(days=31)  # 简单处理，一个月加30天
        tasks_next_month = Task.query.filter(Task.due_date >= next_month_start, Task.due_date < next_month_end).all()
        tasks_results["tasks_next_month"].extend( [{
            "task_id": task.task_id,
            "title": task.title,
            "due_date": task.due_date.isoformat()
        } for task in tasks_next_month] )

    #return jsonify([tasks_results, tasks_results2]), 200
    return jsonify(tasks_results), 200

